from panda3d.core import *
import random, sys, os, math
from direct.filter.CommonFilters import CommonFilters
from direct.filter.FilterManager import FilterManager
from direct.task import Task
from direct.interval.IntervalGlobal import *


class Map():
        def __init__(self,Name,Config):#load map mesh--create lights--create pre process--create post process
                self.MapName = Name
                self.Config = Config
                self.MapMesh = 0
                self.SkyMesh = 0
                self.SpawnsCT = 0
                self.SpawnsT = 0
                self.LightList = 0
                self.CreateMesh()
                
        def CreateMesh(self):
                self.MapMesh = loader.loadModel("maps/"+self.MapName+"/"+self.MapName)
                self.MapMesh.setHpr(0,180,0)
                self.MapMesh.setPos(0,0,0)
                self.MapMesh.reparentTo(render)
        #--------------------Change all textures to higher filtering---------------------#
                for tex in self.MapMesh.getChild(0).find("Mesh").findAllTextures():
                        tex.setAnisotropicDegree(16)
        #--------------------Create Spawns-----------------------------------------------#
                self.SpawnsCT = self.MapMesh.findAllMatches("**/Cstart*")
                self.SpawnsT = self.MapMesh.findAllMatches("**/Tstart*")
        #--------------------Create SkyBox-----------------------------------------------#
                self.skydome = loader.loadModel("models/skybox")
                self.skydome.setScale(200,200,200)
                self.skydome.reparentTo(render)
                self.skydome.setPos(0,0,-20)
                self.skydome.setBin('background', 0)
                self.skydome.setDepthWrite(0)
                self.skydome.setLightOff()
        #--------------------Physics-----------------------------------------------------#
                base.Physics.LoadMapPhysics(self.MapMesh)
                base.Physics.pController.setPos(Point3(0,0,0))
        def Update(self,task):
                self.skydome.setPos(base.camera.getPos(render))
                return task.cont
        
#def LoadMap(self,mapname):
#
#        self.terrain.reparentTo(self.render)
#        base.Physics1.LoadMapPhysics(mapname)
#        base.r = 0.01
#        base.g = 0.0601
#        base.b = 0.0501
#        self.light = Vec3(0,0,1)
#        if base.Player1.team == 0:#NOTE --- Forseeable problems this method needs expansion on server and client. 0 is ct
#            pos = Point3(base.MapSpawnsCT[0].getPos()+Point3(0,0,1))
#            switch = pos.getY()
#            pos.y = -pos.getZ()
#            pos.z = -switch
#            base.Physics1.pController.setPos(Point3(0,0,0))
#        else:
#            pos = Point3(base.MapSpawnsT[0].getPos()+Point3(0,0,0))
#            switch = pos.getY()
#            pos.y = -pos.getZ()
#            pos.z = -switch
#            base.Physics1.pController.setPos(Point3(0,0,1))
#def SkyScattering(task):
#        invWaveLength = Vec3(1/pow(0.650,4),1/pow(0.570,4),1/pow(0.475,4))
#	outerR = 102.50;
#	outerR2 = outerR*outerR;
#	innerR = 100.0;
#	innerR2 = innerR*innerR;
#	nSamples = 10.0;		
#	m_Kr = 0.0025;		
#	m_Kr4PI = m_Kr*4.0*math.pi;
#	m_Km = 0.0015;		
#	m_Km4PI = m_Km*4.0*math.pi;
#	m_ESun = 25.0;		
#	m_g = -0.95;		
#	m_g2 = m_g*m_g;
#	krEsun = m_Kr*m_ESun;
#	kmEsun = m_Km*m_ESun;
#        camH = base.cam.getPos(render)
#        base.sky.setShaderInput("v3CameraPos",base.cam.getPos(render))
#        base.sky.setShaderInput("v3LightPos",base.dlnp.getPos(render)/base.dlnp.getPos(render).length())
#        base.sky.setShaderInput("v3InvWavelength",invWaveLength)
#        base.sky.setShaderInput("fCameraHeight",camH.length())
#        base.sky.setShaderInput("fCameraHeight2",camH.length()*camH.length())
#        base.sky.setShaderInput("fOuterRadius",outerR)
#        base.sky.setShaderInput("fOuterRadius2",outerR2)
#        base.sky.setShaderInput("fInnerRadius",innerR)
#        base.sky.setShaderInput("fInnerRadius2",innerR2)
#        base.sky.setShaderInput("fKrESun",krEsun)
#        base.sky.setShaderInput("fKmESun",kmEsun)
#        base.sky.setShaderInput("fKr4PI",m_Kr4PI)
#        base.sky.setShaderInput("fKm4PI",m_Km4PI)
#        base.sky.setShaderInput("g",m_g)
#        base.sky.setShaderInput("g2",m_g2)
#        #base.sky.reparentTo(render)
#        base.sky.setScale(102.50)
#        return Task.cont
#def LoadLights(self):
#    self.lighting = True
#    self.dlight = Spotlight('slight')
#    self.dlight.getLens().setNearFar(1, 100)
#    self.dlight.getLens().setFov(90)
#    self.dlnp = self.render.attachNewNode(self.dlight)
#    self.dlnp.setPos(Vec3(8,-9,104))
#    self.dlnp.lookAt(0,0,101)
#    alight = AmbientLight('alight')
#    alight.setColor(VBase4(0.2, 0.2, 0.2, 1))
#    self.alnp = render.attachNewNode(alight)
#    height = 40
#    length = 20
#    speed = 60
#    base.dlnp.setPos(-30,length,height-20)
#def UpdateOne(self):
#    #if base.event.IsInView(base.watermesh):
#      #  base.buffer.setActive(0)
#    return Task.again
#def Reflection(self):
#        resolution = 1
#        #generate mesh
#        self.watermesh=render.attachNewNode("dummyNode")
#        cm = CardMaker('card')
#        for x in range(resolution):
#            for y in range(resolution):
#                card = render.attachNewNode(cm.generate())
#                card.setPos(x,y,0)
#                card.setHpr(0,-90,0)
#                card.reparentTo(self.watermesh)
#        base.watermesh.flattenStrong()
#        #create reflection buffer
#        samples = 1024
#        self.rig = NodePath('rig')
#        self.buffer = base.win.makeCubeMap('env', samples, self.rig)
#        self.rig.reparentTo(render)
#        self.rig.setPos(5,5,0)
#        lens = self.rig.findAllMatches('**/+Camera')
#        for i in range(len(lens)):
#            lens[i].node().getLens().setNearFar(.1, 100)
#            lens[i].node().setCameraMask(BitMask32.bit(0))
#        base.watermesh.hide(BitMask32.bit(0))
#        base.Player1.ownmodel.hide(BitMask32.bit(0))
#        scale = 15
#        self.watermesh.setScale(scale,scale,1)
#        base.watermesh.setPos(-scale/2,-scale/2,0)
#        cubemap = self.buffer.getTexture()
#        cubemap.setMinfilter(Texture.FTLinearMipmapLinear)
#        cubemap.setMagfilter(Texture.FTLinearMipmapLinear)
#        bumpMap = loader.loadTexture("textures/skybox/bump_water.png")
#        ts = TextureStage('ts')
#        ts.setMode(TextureStage.MModulate)
#        base.watermesh.setTexture(ts, bumpMap)
#        base.watermesh.setShader(Shader.load('shaders\water_test.cg'))
#        base.watermesh.setShaderInput('bump',bumpMap)
#        base.watermesh.setShaderInput('etaRatio',0.66,1,1,1)
#        base.watermesh.setShaderInput('param1',1.0,1.0,globalClock.getFrameTime(),globalClock.getFrameTime())
#        base.watermesh.setShaderInput('texcube',self.buffer.getTexture())
#        base.watermesh.setShaderInput('eyePositionW',base.camera.getPos(render))
#        base.watermesh.setShaderInput('lightPos',base.dlnp.getPos())
#        base.watermesh.hide()
#    
#def Bloom(self):
#    filters = CommonFilters(base.win, base.cam)
#    filters.setBloom(intensity = 1.0,desat = 0)
#
#def ShadowMapping(self):
#        ShadowMap=Texture()
#        ShadowMap.setFormat(Texture.FDepthComponent) #to store depth value instead of color
#        ShadowMap.setMinfilter(Texture.FTLinear)#Texture.FTShadow)     #to use OpenGL SGIX_shadow extension
#        ShadowMap.setMagfilter(Texture.FTLinear)#Texture.FTShadow)
#        ShadowMap.setWrapU(Texture.WMBorderColor)
#        ShadowMap.setWrapV(Texture.WMBorderColor)
#        ShadowMap.setBorderColor(Vec4(1,1,1,1))
#        samples = 4
#        self.mapsize = (1024*samples)
#        base.LBuffer=base.win.makeTextureBuffer('depthmap',self.mapsize,self.mapsize,ShadowMap)
#        self.LCam=base.makeCamera(base.LBuffer)
#        self.LCam.node().setTagStateKey("ShadowCull")
#        self.LCam.node().setTagState("True", RenderState.make(CullFaceAttrib.make(CullFaceAttrib.MCullNone)))
#        base.terrain.setTag("ShadowCull", "True")
#        self.LCam.node().setScene(render)
#        self.LCam.reparentTo(self.dlnp)
#        lens = OrthographicLens()
#        self.LCam.node().setLens(lens)
#        self.LCam.node().showFrustum()
#        self.LCam.node().getLens().setFilmSize(120,120)
#        self.LCam.node().getLens().setNearFar(.01,1000)
#
#        # default values
#        self.pushBias=0.04
#        self.ambient=0.5
#
#        # setting up shader
#        render.setShaderInput('light',self.LCam)
#        render.setShaderInput('ShadowMap',ShadowMap)
#        render.setShaderInput('AlphaMap',ShadowMap)
#        render.setShaderInput('ambient',self.ambient,0,0,1.0)
#        render.setShaderInput('texDisable',0,0,0,0)
#        render.setShaderInput('scale',1,1,1,1)
#        render.setShaderInput('samples',30)
#        render.setShaderInput('push',self.pushBias,self.pushBias,self.pushBias,0)
#
#        # Put a shader on the Light camera.
#        lci = NodePath(PandaNode("Light Camera Initializer"))
#        lci.setShader(Shader.load('shaders\caster.cg'))
#        self.LCam.node().setInitialState(lci.getState())
#
#         #Put a shader on the Main camera.
#        mci = NodePath(PandaNode("Main Camera Initializer"))
#        mci.setShader(Shader.load('shaders\Shadows_pcf_test.cg'))
#        #Shadows_NVIDIA_PCF,Shadows_ATI_PCF,Shadows - 3 different shadow shaders
#        base.cam.node().setInitialState(mci.getState())

